ES6의 모듈
기존의 모듈,es6의 새로운 모듈에 대해 알아보자
2023-06-19
CommonJS에서의 모듈
CommonJS는 2009년에 만들어진, 자바스크립트 모듈을 만들기 위한 일종의 규칙입니다. 이 방법은 원래 브라우저를 위한 것이 아닌, 서버사이드 애플리케이션을 위해 만들어 졌습니다.
CommonJs로 모듈을 정의해, 이를 export를 하고 다른 모듈에서 import를 합니다.
그러나, Common Js는 몇 가지 문제점이 있었습니다.
-
언어 표준이 아닌 CommonJs
- CommonJs는 자바스크립트 언어 표준이 아니었기 떄문에, Node를 지원하고 CommonJs 모듈시스템을 지원하는 런타임에서만 사용가능합니다.
-
require는 함수이기 때문에 누구나 마음대로 동작을 바꿀 수 있습니다.
위의 코드처럼 재정의하는 것도 가능합니다. 이러한 경의 예측 가능하지 못한 동작 을 야기할 수 있습니다.
CommonJS의 번들 크기 측정
먼저 번들은 웹 애플리케이션에서 여러 파일을 하나로 묶는 것입니다. 이렇게 번들된 파일이 웹 페이지에서 로드되어 실행됩니다.
그리고 이렇게 여러 파일을 묶고 압축해주는 작업을 모듈 번들링이라고 부릅니
다.
먼저 다음과 같은 함수를 정의했습니다.
그리고 이 함수를 index.js의 파일에서 일부 또는 전체를 가져와 사용 가능합니다.
먼저 웹펙을 이용해, 두 폴더 utils.js, index.js만 있는 상태에서 앱을 빌드했습니다 .
먼저 Common JS를 사용했을 떄 웹팩을 이용해 번들을 하면 out.js에 다음과 같은 결과 를 얻었습니다.
out.js의 번들된 크기가 87.9 KiB인 것을 확인할 수 있습니다. index.js에는 어떤 lodash패키지도 없지만, 엄청난 lodash관련 내용과 utils.js의 함수가 포함되어 있습 니다.
ES6의 모듈
import는 export로 내보내진 변수,함수 등등을 불러올 수 있는 키워드입니다.
ES6 모듈의 장점들
이렇게 하면 각 JS별로 사용되는 모듈을 명시적으로 Import해오기 때문에, 스크립트를 추적하기 쉬워집니다.
또한 무분별한 전역 오염을 방지할 수 있습니다.
웹팩을 이용해 동일한 utils.js,index.js를 ES6의 모듈시스템으로 바꿔보았습니다.
그리고 웹팩을 실행하면 다음의 결과를 얻을 수 있습니다. out.js의 코드와 함께 무려 38 바이트의 크기를 갖는 것을 확인할 수 있습니다.
lodash도 찾아볼 수 없고 utils.js의 코드도 사라진 것을 볼 수 있습니다.
CommonJs모듈은 일반적으로 최적화를 진행하기 어렵습니다. 번들러가 더 성공적으로애 플리케이션을 최적화하게 하려면 CommonJS모듈모다 ECMA모듈을 쓰는 것이 더 좋습니다 .
CommonJS의 번들크기가 ECMA모듈모다 더 큰 이유?
먼저 웹팩의 ModuleConcatenationPlugin은 웹팩의 플러그인입니다. 앞서 웹펙 의 설정에서 production mode를 켜줬는데 production mode가 활성화되면 ModuleConcatenationPlugin이 자동으로 활성화됩니다(3버전 이상)
이 플러그인은 연속된 모듈을 하나의 함수로 결합(concatenate)하여 중복 코드를 제거 합니다.
만약 utils.js의 동일한 subtract함수를 index.js에서 정의하면 어떻게 될까요? 예를 들어
위의 index.js에서는 utils.js의 substract를 그대로 정의합니다. 웹팩을 이용해 빌드 하면 다음의 결과가 나옵니다.
위의 출력에서 모든 함수가 동일한 네임스페이스안에 있습니다. 충돌을 막기위 해 index.js의 substract함수이름을 index_substract로 변경했습니다.
사용하지 않는 import를 정리하는 것을 트리쉐이킹이라고 합니다. 트리 쉐이킹은 웹픽이 utils.js에서 import하는 것과 어떤 것을 export하는지 빌드타임에 정적으로 이해했기 떄문에 가능합니다.
이러한 기능은 CommonJs방식과 비교했을 떄 더 명확해지는데, 같은 예제를 CommonJs방 식으로 실행해보겠습니다.
out의 크기가 너무 커져서 다음의 코드만 살펴보겠습니다.
이 빌드에서는 코드 실행 시 add함수를 (0,_utilsWEBPACK_IMPORTED_MODULE_0/_ .add _/ .IH)(1, 2) - _utilsWEBPACK_IMPORTED_MODULE_0 모듈에서 동적으로 불러 오고 있는 것을 볼 수 있습니다.
결론
번들러가 애플리케이션 최적화를 진행하게, ECMA모듈을 잘 쓰자..!